function Player() {

	this.speed =9;
	this.brakingFactor = 0.3;
	this.maxSpeed = 8;
	this.jumpSpeed = 75;
	this.airBrakeStrength = 200;
        this.inAirFriction = 0.001;
        this.groundedFriction = 0.2; 
	this.faceForwardDelay = 300; //time the player will run bakwards after firing a shot

	this.playerNormal = box2d.b2Vec2(0,0);
	this.jumping = 0;
	
	this.spritecontainer;
	this.x = 400;
	this.y = 600;

	this.handsOffset = {x: -14, y: 46};
	//this.muzzleOffset = {x: 34, y: 10}; //coordinates relative to handsOffset
	this.muzzleOffset = {x: 34, y: 10}; //coordinates relative to handsOffset

	this.movementAxis = v.zero;
	
	this.lastFired = 0;
	this.recoil = {x:0,y:0};

        this.facing = v.left;
	
	this.setupView();
	this.setupPhysics();
}

Player.prototype = {

	
	setupView: function() {

		this.spriteContainer = new createjs.Container();
		this.spriteContainer.x = this.x;
		this.spriteContainer.y = this.y;

		var playerBodySprite = new createjs.Bitmap('assets/boxer.png');
		
		this.width = playerBodySprite.image.width * .5; 
		this.height = playerBodySprite.image.height * .5;
		
		playerBodySprite.regX = this.width;
		playerBodySprite.y = -40;

		var playerHandsSprite = new createjs.Bitmap('assets/rifle.png');
		playerHandsSprite.regX = this.width;
		playerHandsSprite.regY = this.height;
		playerHandsSprite.x = this.handsOffset.x;
		playerHandsSprite.y = this.handsOffset.y;

		this.spriteContainer.addChild(playerBodySprite,playerHandsSprite);
		
		//this.width = this.spriteContainer.children[0].image.width * .5; 
		
		//this.playerImage.scaleX = this.playerImage.scaleY = 0.8;
		//
		stage.addChild(this.spriteContainer);
		
		/*
		var spriteSheet = {
 		 	"animations": {"run": [0, 25], "jump": [26, 63]}, 
			"images": ["../assets/spritelib_gpl/shooter/action1.png"], 
			"frames": {"regX": 0, "height": 292.5, "count": 64, "regY": 0, "width": 165.75}
		};
		
		var ss = new createjs.SpriteSheet(spriteSheet);
		var playerView = new createjs.BitmapAnimation(ss);
		
		// Set up looping
		ss.getAnimation("run").next = "run";
		ss.getAnimation("jump").next = "run";
		playerView.gotoAndPlay("run");
		
		playerView.x = -200;
		playerView.y = 90;
		playerView.scaleX = playerView.scaleY = 0.8;
		
		var assets = [];

		var manifest = [
			{src:"../assets/spritelib_gpl/shooter/action1.png", id:"player"}
		];

		var loader = new createjs.LoadQueue(false);
		loader.onFileLoad = function() { assets.push(event.item); };
		loader.onComplete = function() {
			for(var i = 0; i < assets.length; i++) {
				var item = assets[i];
				var result = loader.getResult(item.id);
			}
		};
		loader.loadManifest(manifest);
		stage.autoClear = false;
		*/
	},
	
	setupPhysics: function() {
		var fixDef = new box2d.b2FixtureDef();
		fixDef.density = 1;
		fixDef.friction = this.groundedFriction;
		fixDef.shape = new box2d.b2PolygonShape();
		fixDef.shape.SetAsBox(this.width / SCALE, this.height / SCALE);
		fixDef.filter.groupIndex = -1;
		
		var playerDef = new box2d.b2BodyDef();
		playerDef.type = box2d.b2Body.b2_dynamicBody;
		playerDef.position.x = this.x / SCALE;
		playerDef.position.y = this.y / SCALE;
		playerDef.fixedRotation = true;
		
		this.playerBody = world.CreateBody(playerDef);
		this.playerBody.CreateFixture(fixDef);
		
		this.z = 0;

                /*

                // define sensor on bottom
		var fixDefSensor = new box2d.b2FixtureDef();
                fixDefSensor.friction= 3;
                fixDefSensor.isSensor = true;
                
		fixDefSensor.shape = new box2d.b2PolygonShape();
        pos =  new box2d.b2Vec2((playerDef.position.x - this.width / 2) / SCALE, (playerDef.position.y + 10) / SCALE);
        console.log(playerDef);
		fixDefSensor.shape.SetAsOrientedBox(this.width / SCALE, 1 / SCALE, pos, 0.0);
		fixDefSensor.filter.groupIndex = -1;

		this.playerBody.CreateFixture(fixDefSensor);
	        console.log(this.playerBody.GetFixtureList()); */ 
	},
	
	handleInput: function() {
		var now = new Date().getTime();

		//running
		if(input.xAxisLeft && this.playerBody.GetLinearVelocity().x * input.xAxisLeft < this.maxSpeed) {
			this.playerBody.ApplyImpulse(new box2d.b2Vec2(this.speed * input.xAxisLeft, 0), this.playerBody.GetWorldCenter());
	
			//don't face forward for some time after shooting
			
			if (now - this.lastFired > this.faceForwardDelay) {
				if (input.xAxisLeft < 0) this.setFacing(v.left);
				else this.setFacing(v.right);
			}

 		}

		//ducking
		if (input.yAxisLeft < 0) {
			this.height = 25;  //imagine using a different sprite and actually changing the fixture to a smaller one		
		//stopping
		} else if (input.xAxisLeft == 0 && this.jumping == false) {
			this.playerBody.ApplyImpulse(new box2d.b2Vec2(this.playerBody.GetLinearVelocity().x *  -this.brakingFactor,0), this.playerBody.GetWorldCenter());
			this.height = 30;
		}
		
	
		//jumping
		if(input.yAxisLeft > 0 && this.canJump()) { 
			this.playerBody.ApplyImpulse(new box2d.b2Vec2(0, -this.jumpSpeed), this.playerBody.GetWorldCenter());
			this.jumping = true;
		}

		//canceling a jump
		if (this.jumping && input.yAxisLeft == 0) {
			this.playerBody.ApplyForce(new box2d.b2Vec2(0, this.airBrakeStrength), this.playerBody.GetWorldCenter());
		}

		//shooting
		if (input.xAxisRight || input.yAxisRight) {
			var dFire = ((now) - this.lastFired) / 1000;
			if(dFire >= 0.3) {


				bulletList.push(new Bullet({
					spawnX: this.x + this.muzzleOffset.x * this.facing.x,
					spawnY: this.y + this.muzzleOffset.y,
					dirX: input.xAxisRight,
					dirY: input.yAxisRight * -1
				}));

				//prime recoil animation

				if (this.recoil.x == 0 && this.recoil.y == 0) {
					this.recoil = {x: Math.abs(input.xAxisRight) * 2, y: input.yAxisRight * 2}; // x should always be the 'local backwards' or zero
				} else {
					this.recoil = {x: 0, y: 0};
				}

	
				//bullet.ApplyImpulse(new box2d.b2Vec2(-40, 0), bullet.GetWorldCenter());
				this.lastFired = new Date().getTime();
			}
			
			if (input.xAxisRight < 0) this.setFacing(v.left);
			else this.setFacing(v.right);
		}


	},
	
	
	
	createBullet: function(x,y) {
		/* 
		var fixDef = new box2d.b2FixtureDef();
		fixDef.density = 10;
		fixDef.friction = 0.2;
		fixDef.restitution = 0.2;
		fixDef.shape = new box2d.b2PolygonShape();
		fixDef.shape.SetAsBox(5/SCALE, 1/SCALE);
		fixDef.filter.groupIndex = -1;
		
		var bulletDef = new box2d.b2BodyDef();
		bulletDef.type = box2d.b2Body.b2_dynamicBody;
		//bulletDef.IsBullet = true;
		//bulletDef.position.x = this.x - 30 / SCALE;
		//bulletDef.position.y = this.y - 10 / SCALE;
		bulletDef.position.x = this.x / SCALE;
		bulletDef.position.y = this.y / SCALE;
		//bulletDef.gravityScale(0);
		bulletDef.linearDamping = 0;
		bulletDef.angularDamping = 0;
		var bulletBody = world.CreateBody(bulletDef)
		bulletBody.CreateFixture(fixDef);
		bulletBody.SetBullet(true);*/
		
		var bulletBody = new Bullet({
			spawnX: this.x + this.muzzleOffset.x,
			spawnY: this.y + this.muzzleOffset.y,
		    	dirX: x,
			dirY: y
		}) ;
		bulletList.push(bulletBody);
		
		document.getElementById('debug').innerHTML = bulletList.length;
		
		return bulletBody;
	},
	
	canJump: function() {
		if(this.jumping == 0 && this.playerBody.GetLinearVelocity().y > -0.99 && this.playerBody.GetLinearVelocity().y < 0.01) { 
                        this.playerBody.GetFixtureList().m_friction = this.inAirFriction;
			return true;
                }
		return false;
	},
	
        setFacing: function(direction) {
		this.facing = direction;
		// flip the image acording to v
                this.spriteContainer.scaleX = direction.x * -1;
        },

	update: function() {
		this.handleInput();

		this.x = this.playerBody.GetWorldCenter().x * SCALE;
		this.y = this.playerBody.GetWorldCenter().y * SCALE;
		
		// keep the image on top of the box2d object
		this.spriteContainer.set({
			x:this.x,
			y:this.y
		});


		if (((new Date().getTime()) - this.lastFired) > 100) {
			this.recoil = {x:0,y:0};
		}
		this.spriteContainer.children[1].x = this.handsOffset.x + this.recoil.x;
		this.spriteContainer.children[1].y = this.handsOffset.y + this.recoil.y;

	},

        handleContact: function(contact,worldManifold) {
		if(worldManifold.m_normal.y > 0) {
                        
			var vec = player.playerBody.GetLinearVelocity()
			if(player.jumping > 1) { // <--- without this we can do a double jump :D
				//vec.y = 0
				//SetLinearVelocity(vec)
				//console.log(vec)
				this.jumping = false;
                                this.playerBody.GetFixtureList().m_friction = this.groundedFriction;
			} else if(player.jumping == 1){
				this.jumping = 2;
			}
		}
        }
}
